
package com.e885.hibernate;

import java.io.Serializable;

import org.hibernate.Query;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;

/**
 * Data access object (DAO) for domain model
 * 
 * @author Eric.Kao(gau168.gau@msa.hinet.net)
 * @version 1.0
 * @company E885 Group
 * @copyright Copyright (c) 2001-2008
 */
public abstract class BaseHibernateDAO< T extends Serializable >
{
	private Session session;

	public BaseHibernateDAO()
	{
		session = HibernateSessionFactory.getSession();
	}

	/**
	 * delete
	 * 
	 * @param persistentInstance
	 */
	public void delete( T persistentInstance )
	{
		session.delete( persistentInstance );
	}

	/**
	 * findById
	 * 
	 * @param entityName
	 * @param id
	 * @return
	 */
	public<T> T findById( Class theClass, Serializable id )
	{	
		return (T)session.get( theClass, id );
	}

	/**
	 * get queyr By name
	 * 
	 * @param queryName
	 * @return
	 */
	protected Query getNameQuery( String queryName )
	{
		return session.getNamedQuery( queryName );
	}

	/**
	 * 處理分頁
	 * 
	 * @param query the instance of the Query
	 * @param page 目前頁碼
	 * @param pageSize 每頁筆數
	 * @return
	 */
	protected Pagination processPagination( Query query, int page, int pageSize )
	{
		if( page <= 0 )
			throw new IllegalArgumentException( "currentPage 必需大於 0" );

		ScrollableResults scrollableResults = query.scroll();

		query.setFirstResult( ( page - 1 ) * pageSize );
		query.setMaxResults( pageSize + 1 );

		scrollableResults.last();

		Pagination pagination = new Pagination( query.list(), page, pageSize, scrollableResults.getRowNumber() + 1 );

		scrollableResults.close();
		scrollableResults = null;

		return pagination;
	}

	/**
	 * 處理分頁
	 * 
	 * @param query the instance of the Query
	 * @param currentPage 目前頁碼
	 * @return
	 */
	protected Pagination ProcessPagination( Query query, int currentPage )
	{
		return processPagination( query, currentPage, 10 );
	}

	/**
	 * save
	 * 
	 * @param transientInstance
	 */
	public Object save( T transientInstance )
	{
		return session.save( transientInstance );
	}

	/**
	 * save or update
	 * 
	 * @param instance
	 */
	public void saveOrUpdate( T instance )
	{
		session.saveOrUpdate( instance );
	}

	/**
	 * update
	 * 
	 * @param persistentInstance
	 */
	public void update( T persistentInstance )
	{
		session.update( persistentInstance );
	}
}